// 权限操作

/**
 * 目标 对用户权限（可读 可写 可操作 等）进行高效管理
 * 
 * 设计
 *  1 使用不同的二进制位进行管理
 *  2 将用户的几种权限的二进制位进行 或 运算操作 即可 得到其所有权限 （或的运算符是 有真即为真）0100 | 0001 = 0101
 *  3 若想判断当前权限中是否拥有某权限的话可使用 & 且运算符比如（01 & 11 == 01 说明有01权限）
 *  4 若想去掉用户某权限可使用 所有权限 且 取反之后的某权限 即可得到剩余权限 如 1111 & ~0001 = 1110
 * 
 * 
 * 其他知识点
 *  1 打印2进制数据可使用 toString(2) 其中传入的2就是二进制的意思
 *  2 | & ~ 运算符的优先级是低于 == 的。所以判断中带有位运算符的时候需要用括号括起来
 */

let canRead = 0b0001; // 可读
let canWhite = 0b0010; // 可写
let canDel = 0b0100; // 可删除
let canCreate = 0b1000; // 可创建

let x1 = canRead | canWhite | canDel | canCreate;
console.log('用户拥有的所有权限是：', x1.toString(2));

// 若想判断当前权限中是否拥有某权限可使用且 
// 比如 当前有所有权限 1111 和 可读权限 判断的时候 1111 & 0001 结果就是 0001
// 结果和指定判断的权限相等说明 其就拥有此权限
if ((x1 & canRead) === canRead) {
    console.log('可读取权限：',true, canRead.toString(2));
} else {
    console.log('可读取权限：',false, canRead.toString(2));
}

if ((x1 & canCreate) === canCreate) {
    console.log('可创建权限：', true, canCreate.toString(2));
} else {
    console.log('可创建权限：', false, canCreate.toString(2));
}

console.log('可读权限：', canRead.toString(2));
let qf = ~canRead;
console.log('可读权限求反：', qf.toString(2));

// 若想剔除某权限 可先将权限取反 如 0001 -》 0010 再和用户已有权限1111做 & 的操作 接口得到 1110 即剔除了
// 取反操作可使用 ~0001  
console.log('去掉可读权限 之前---》', x1.toString(2)); // 1111
let noRead = x1 & ~canRead
console.log('去掉可读权限 之后---》', noRead.toString(2)); // 1110